﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using Cosmos.Assembler.x86;
using SYS = Cosmos.System;
using DimOS.Constants;
using DimOS.DimFS;
using TERM = DimOS.DimSH.Terminal;
using SH = DimOS.DimSH.Shell;
using DimOS.Internals;
using DimOS.Plugs;
using DimOS.VTS;
using Console = System.Console;
using String = DimOS.Plugs.String;
using HAL = Cosmos.Hardware;

namespace DimOS.DimSH
{
    public static class Interface
    {                                                                //change this
        //public static TextScreen Screen = Settings.AdvancedTerminal ? new Screen() : new TextScreen();

        public static int Columns = Settings.AdvancedTerminal ? Screen.TotalColumns : HAL.Global.TextScreen.Cols;
        public static int Rows = Settings.AdvancedTerminal ? Screen.TotalRows : HAL.Global.TextScreen.Rows;

        public static int InfoColumns = 14;
        public static int OutputColumns = Columns - InfoColumns;

        public static int ColumnOffset = 0;
        public static int RowOffset = 0;
        public static bool PanelView = false;

        public static int X { get { return Settings.AdvancedTerminal ? VTS.Console.X : SYS.Global.Console.X; }
            set { if (Settings.AdvancedTerminal) VTS.Console.X = value; else SYS.Global.Console.X = value; } }
        public static int Y { get { return Settings.AdvancedTerminal ? VTS.Console.Y : SYS.Global.Console.Y; }
            set { if (Settings.AdvancedTerminal) VTS.Console.Y = value; else SYS.Global.Console.Y = value; } }

        public static ConsoleColor Background
        {
            get { return Settings.AdvancedTerminal ? VTS.Console.Background : Console.BackgroundColor; }
            set { if (Settings.AdvancedTerminal) VTS.Console.Background = value; else Console.BackgroundColor = value; }
        }

        public static ConsoleColor Foreground
        {
            get { return Settings.AdvancedTerminal ? VTS.Console.Foreground : Console.ForegroundColor; }
            set { if (Settings.AdvancedTerminal) VTS.Console.Foreground = value; else Console.ForegroundColor = value; }
        }

        private static int _failIndicatorX;
        private static int _failIndicatorY;

        public static string InfoSpaceSplitter = "";
        public static string InfoSectionSplitter = "";
        public static string OutputSpaceSplitter = "";
        public static string OutputSectionSplitter = "";
        public static string OutputInitSplitter = "";
        public static string JournalSplitter = "";

        private static void ClearRowInfo(int y)
        {
            X = OutputColumns; Y = y;
            TERM.Write(InfoSpaceSplitter, false, true, false, false);
        }

        //Clears Current Topic part of Information section
        public static void ClearCurrentTopic() { for (int i = 0; i < 2; i++) ClearRowInfo(i); }

        //Clears the Study Tools (targets, quizzes, etc.) part of Information section
        public static void ClearStudyTools() { for (int i = 3; i < 9; i++) ClearRowInfo(i); }

        //Clears the AI Tutor part of Information section
        public static void ClearTutor() { for (int i = 10; i <= Rows - 10; i++) ClearRowInfo(i); }

        //Clears the Help part of Information section
        public static void ClearHelp() { for (int i = Rows - 8; i <= Rows - 5; i++) ClearRowInfo(i); }

        //Clears the Clock part of Information section
        public static void ClearClock() { for (int i = Rows - 3; i <= Rows - 2; i++) ClearRowInfo(i); }

        public static void ClearScreens() { ClearRowInfo(Rows - 1); }

        //Clears the Path (working directory) section
        public static void ClearPath(bool mainScreenOnly = false) { var y = Rows - 2 - RowOffset; X = 0;
        Y = (y < 0) ? 0 : y; TERM.Write(OutputSpaceSplitter, false, false, false, true, mainScreenOnly); }

        public static void ClearPanel() { Y = Rows - 2; X = 0; TERM
        .Write(OutputSpaceSplitter, false, false, false, true, true); }

        public static void ClearSections()
        {
            var posX = X;
            var posY = Y;
            var color = Background;

            Background = Colors.SectionInfoBackground;
            ClearCurrentTopic();
            ClearRowInfo(2);
            ClearStudyTools();
            ClearRowInfo(9);
            ClearTutor();
            ClearRowInfo(Rows - 9);
            ClearHelp();
            ClearRowInfo(Rows - 4);
            ClearClock();

            Background = Colors.SectionScreensBackground;
            ClearScreens();

            Background = Colors.SectionOutputBackground;
            ClearPath();

            X = posX;
            Y = posY;
            Background = color;
        }


        //Draws Current Topic part of Information section
        public static void DrawCurrentTopic()
        {
            X = OutputColumns; Y = 0;
            Foreground = Colors.CaptionCurrentTopicKey;
            TERM.Write(Captions.CurrentTopic, false, true, false, false);

            X = OutputColumns; Y = 1;
            Foreground = Colors.CaptionCurrentTopicValue;
            TERM.Write(SH.CurrentTopic.Length > InfoColumns 
                ? SH.CurrentTopic.Remove(InfoColumns) 
                : SH.CurrentTopic, false, true, false, false);
        }

        private static void DrawStudyTool(int row, string caption, int done, int count)
        {
            X = OutputColumns; Y = row;
            Foreground = Colors.CaptionStudyToolsKey;
            TERM.Write(caption, false);
            Foreground = Colors.CaptionStudyToolsValue;
            TERM.Write(done.ToString().PadLeft(2, '0') + Separators.StudyToolsDelimiter
                + count.ToString().PadLeft(2, '0'), false, true, false, false);
        }

        //Draws the Study Tools (targets, quizzes, etc.) part of Information section
        public static void DrawStudyTools()
        {
            DrawStudyTool(3, Captions.Targets, SH.TargetsDone, SH.Targets.Count);
            DrawStudyTool(4, Captions.Quizzes, SH.QuizzesDone, SH.Quizzes.Count);
            DrawStudyTool(5, Captions.Guesses, SH.GuessesDone, SH.Guesses.Count);
            DrawStudyTool(6, Captions.Options, SH.OptionsDone, SH.Options.Count);
            DrawStudyTool(7, Captions.Matches, SH.MatchesDone, SH.Matches.Count);
            DrawStudyTool(8, Captions.Scripts, SH.ScriptsDone, SH.Scripts.Count);
        }

        //Draws the AI Tutor part of Information section
        public static void DrawTutor(bool update = true)
        {
            var posX = X;
            var posY = Y;
            var colorF = Foreground;
            var colorB = Background;
            Background = Colors.SectionInfoBackground;

            if (update)
            {
                X = OutputColumns;
                Y = 10;
                Foreground = Colors.CaptionTutorEnclosure;
                TERM.Write(Symbols.CornerTopLeft + Symbols.BorderStopLeft, false);
                Foreground = Colors.CaptionTutorName;
                TERM.Write(Captions.TutorName, false);
                Foreground = Colors.CaptionTutorEnclosure;
                TERM.Write(Symbols.BorderStopRight +
                    Symbols.CornerTopRight, false, true, false, false);

                Foreground = Colors.CaptionTutorEnclosure;
                var output = TERM.Format(SH.TutorOutput, InfoColumns - 2);
                for (int i = 11; i <= Rows - 11; i++)
                {
                    X = OutputColumns;
                    Y = i;
                    TERM.Write(Symbols.BorderVertical, false);
                    if (i - 11 < output.Length)
                    {
                        Foreground = Colors.SectionInfoForeground;
                        TERM.Write(output[i - 11], false);
                    }

                    X = Columns - 1;
                    Y = i;
                    Foreground = Colors.CaptionTutorEnclosure;
                    TERM.Write(Symbols.BorderVertical, false, true, false, false);
                }
                X = OutputColumns;
                Y = Rows - 10;
                TERM.Write(Symbols.CornerBottomLeft, false);
                for (int i = 0; i < InfoColumns - 2; i++) TERM.Write(Symbols.BorderHorizontal, false);
                TERM.Write(Symbols.CornerBottomRight, false, true, false, false);
            }
            else
            {
                Foreground = Colors.SectionInfoForeground;
                var output = TERM.Format(SH.TutorOutput, InfoColumns - 2);
                for (int i = 11; i <= Rows - 11; i++)
                {
                    X = OutputColumns + 1;
                    Y = i;
                    if (i - 11 < output.Length) TERM.Write(output[i - 11], false);
                }
            }

            X = posX; Y = posY;
            Foreground = colorF;
            Background = colorB;
        }

        private static void DrawHelpEntry(int row, string key, string value)
        {
            X = OutputColumns; Y = row;
            Foreground = Colors.CaptionCommandsKey;
            TERM.Write(key, false);
            Foreground = Colors.CaptionCommandsValue;
            TERM.Write(value, false, true, false, false); 
        }

        //Draws the Help part of Information section
        public static void DrawHelp()
        {
            DrawHelpEntry(Rows - 8, Commands.List[0][0].Key + Separators.CommandExtensionDelimiter + '?', Captions.UserProgram);
            DrawHelpEntry(Rows - 7, Commands.List[0][1].Key + Separators.CommandExtensionDelimiter + '?', Captions.SetShell);
            DrawHelpEntry(Rows - 6, Commands.List[0][2].Key + Separators.CommandExtensionDelimiter + '?', Captions.GetShell);
            DrawHelpEntry(Rows - 5, Commands.List[0][3].Key + Separators.CommandExtensionDelimiter + '?', Captions.ClearScreen);
        }

        private static void DrawDate(int row, bool update)
        {
            X = update ? OutputColumns : OutputColumns + Captions.Time.Length;
            Y = row;
            if (update)
            {
                Foreground = Colors.CaptionDateKey;
                TERM.Write(Captions.Date, false);
            }
            Foreground = Colors.CaptionDateValue;
            TERM.Write(HAL.RTC.DayOfTheMonth.ToString().PadLeft(2, '0') + Separators.DateDelimiter
                + HAL.RTC.Month.ToString().PadLeft(2, '0') + Separators.DateDelimiter
                + HAL.RTC.Year.ToString().PadLeft(2, '0'), false, true, false, false);
        }

        private static void DrawTime(int row, bool update)
        {
            X = update ? OutputColumns : OutputColumns + Captions.Time.Length;
            Y = row;
            if (update)
            {
                Foreground = Colors.CaptionTimeKey;
                TERM.Write(Captions.Time, false);
            }
            Foreground = Colors.CaptionTimeValue;
            TERM.Write(HAL.RTC.Hour.ToString().PadLeft(2, '0') + Separators.TimeDelimiter
                + HAL.RTC.Minute.ToString().PadLeft(2, '0') + Separators.TimeDelimiter
                + HAL.RTC.Second.ToString().PadLeft(2, '0'), false, true, false, false);
        }

        //Clears the Clock part of Information section
        public static void DrawClock(bool update = true)
        {
            var posX = X;
            var posY = Y;
            var colorF = Foreground;
            var colorB = Background;
            Background = Colors.SectionInfoBackground;

            DrawDate(Rows - 3, update);
            DrawTime(Rows - 2, update);

            X = posX; Y = posY;
            Foreground = colorF;
            Background = colorB;
        }

        //Clears the Clock part of Information section
        public static void DrawScreens()
        {
            var posX = X; X = OutputColumns + 1;
            var posY = Y; Y = Rows - 1;

            var colorF = Foreground;
            var colorB = Background;

            Foreground = Colors.SeparatorScreen;
            Background = Colors.SectionScreensBackground;

            DrawInputIndicator(SH.InputIndicatorColor);
            TERM.Write(Separators.ScreenDelimiterStart, false);
            for (int i = 0; i < 6; i++)
            {
                if (i != 0) { Foreground = Colors.SeparatorScreen; TERM.Write(Separators.ScreenDelimiterMiddle, false); }
                Foreground = i == TERM.CurrentScreen ? Colors.IndicatorActiveScreen : Colors.IndicatorScreen;
                TERM.Write((i + 1).ToString(), false);
            }
            Foreground = Colors.SeparatorScreen;
            TERM.Write(Separators.ScreenDelimiterEnd, false, true, false, false);
            
            X = posX; Y = posY;
            Foreground = colorF;
            Background = colorB;
        }

        public static void DrawScrollIndicator(bool mainScreenOnly = false)
        {
            if (SH.WorkingDirectory.Length < OutputColumns && PanelView == false)
            {
                var y = Rows - 2 - RowOffset;
                var posX = X; X = OutputColumns - 1;
                var posY = Y; Y = (y < 0) ? 0 : y;
                
                var colorF = Foreground;
                var colorB = Background;
                
                Background = Colors.SectionPathBackground;

                if (RowOffset == 0)
                { 
                    Foreground = Colors.IndicatorScroll;
                    if (TERM.ScrollStatus == 0) TERM.Write(Separators.IndicatorScrollUp, false, false, false, false, mainScreenOnly);
                    if (TERM.ScrollStatus == 1) TERM.Write(Separators.IndicatorScrollDown, false, false, false, false, mainScreenOnly);
                    if (TERM.ScrollStatus == 2) TERM.Write(Separators.IndicatorScrollUpDown, false, false, false, false, mainScreenOnly);
                    if (TERM.ScrollStatus == 3) TERM.Write(Separators.IndicatorScrollUpDownStop, false, false, false, false, mainScreenOnly);
                    if (TERM.ScrollStatus == 4) TERM.Write(Tokens.Space, false, false, false, false, mainScreenOnly);
                }
                else { Foreground = Colors.IndicatorScrollDisabled; TERM.Write
                (Separators.IndicatorScrollDisabled, false, false, false, false, mainScreenOnly); }

                X = posX;
                Y = posY;
                Foreground = colorF;
                Background = colorB;
            }
        }

        public static void DrawInputFitIndicator(int x, int y)
        {
            var posX = X; X = x;
            var posY = Y; Y = y;

            var colorF = Foreground;
            var colorB = Background;

            Foreground = Colors.IndicatorInputFit;
            Background = Colors.SectionInputBackground;

            if (SH.InputFitStatus == 0) TERM.Write(Separators.IndicatorScrollRight, false, false, false, false);
            if (SH.InputFitStatus == 1) TERM.Write(Separators.IndicatorScrollLeft, false, false, false, false);
            if (SH.InputFitStatus == 2) TERM.Write(Separators.IndicatorScrollLeftRight, false, false, false, false);
            if (SH.InputFitStatus == 3) TERM.Write(Separators.IndicatorScrollStop, false, false, false, false);

            X = posX;
            Y = posY;
            Foreground = colorF;
            Background = colorB;
        }

        public static void DrawInputIndicator(ConsoleColor color)
        {
            var posX = X; X = OutputColumns;
            var posY = Y; Y = Rows - 1;

            var colorF = Foreground;
            var colorB = Background;

            Foreground = Colors.SeparatorScreen;
            Background = color;

            TERM.Write(Separators.ScreenDelimiterStart.ToString(), false);

            X = posX; Y = posY;
            Foreground = colorF;
            Background = colorB;
        }

        //Clears the Path (working directory) section
        public static void DrawPath(bool mainScreenOnly = false)
        {
            if (PanelView == false)
            {
                var posX = X;
                var posY = Y;
                var colorF = Foreground;
                var colorB = Background;
                Background = Colors.SectionPathBackground;

                var path = SH.WorkingDirectory.Length > OutputColumns
                    ? (SH.WorkingDirectory.Remove(OutputColumns - 1) + Separators.PathFit) 
                    : SH.WorkingDirectory;

                Foreground = Colors.SectionPathForeground;
                var y = Rows - 2 - RowOffset;
                X = 0; Y = (y < 0) ? 0 : y; 
                for (int i = 0; i < path.Length; i++)
                {
                    if (i == path.Length - 1 && path[i] == Separators.PathFit) Foreground = Colors.SeparatorPathFit;

                    if (path[i] == Separators.PathDelimiter)
                    {
                        Foreground = Colors.SeparatorPath;
                        TERM.Write(path[i], false, false, false, true, mainScreenOnly);
                        Foreground = Colors.SectionPathForeground;
                    }
                    else TERM.Write(path[i], false, false, false, true, mainScreenOnly);
                }
                TERM.Write(OutputSpaceSplitter.Remove(0, path
                .Length), false, false, false, true, mainScreenOnly);

                DrawScrollIndicator(mainScreenOnly);

                X = posX; Y = posY;
                Foreground = colorF;
                Background = colorB;
            }
        }

        public static void DrawBufferCell(int index, bool active = false)
        {
            if (index >= ColumnOffset && index <= OutputColumns / 3 - 2 + ColumnOffset)
            {
                var posX = X; X = (index -
                    ColumnOffset) * 3 + 2;
                var posY = Y; Y = Rows - 2;
                var colorF = Foreground;
                var colorB = Background;
                Foreground = active ? Colors.IndicatorActiveBuffer : Colors.IndicatorBuffer;
                Background = Colors.PanelBackground;

                if (SH.Buffer[index] < 0 || SH.Buffer[index] > 255) { Foreground
                = Colors.IndicatorInteger; TERM.Write(Separators.IndicatorInteger,
                false); } else TERM.Write(SH.Buffer[index].ToString().AsByte(), false);

                X = posX; Y = posY;
                Foreground = colorF;
                Background = colorB;
            }
        }

        public static void DrawBuffer()
        {
            var posX = X; X = 0;
            var posY = Y; Y = Rows - 2;
            var colorF = Foreground;
            var colorB = Background;
            Foreground = ColumnOffset > 0
                ? Colors.IndicatorScrollBuffer
                : Colors.IndicatorScrollBufferDisabled;
            Background = Colors.PanelBackground;

            TERM.Write(Separators.IndicatorScrollBufferLeft, false);
            Foreground = Colors.SeparatorBuffer;
            TERM.Write(Separators.BufferDelimiter, false);

            for (int i = 0; i <= OutputColumns / 3 - 2; i++)
            {
                X = i * 3 + 2;
                Foreground = i + ColumnOffset == SH.BufferPointer ?
                Colors.IndicatorActiveBuffer : Colors.IndicatorBuffer;

                if (SH.Buffer[i + ColumnOffset] < 0 || SH.Buffer[i + ColumnOffset] > 255)
                { Foreground = Colors.IndicatorInteger; TERM.Write(Separators.IndicatorInteger,
                false); } else TERM.Write(SH.Buffer[i + ColumnOffset].ToString().AsByte(), false);

                Foreground = Colors.SeparatorBuffer;
                if (i != OutputColumns / 3 - 2) TERM.Write
                (Separators.BufferDelimiter, false);
            }
   
            TERM.Write(Separators.BufferDelimiter, false);
            Foreground = ColumnOffset < SH.Buffer.Length
                ? Colors.IndicatorScrollBuffer
                : Colors.IndicatorScrollBufferDisabled;
            TERM.Write(Separators.IndicatorScrollBufferRight, false, true, false, false);

            X = posX; Y = posY;
            Foreground = colorF;
            Background = colorB;
        }

        public static void DrawPanel()
        {
            var posX = X; X = 0;
            var posY = Y; Y = Rows - 2;
            var colorF = Foreground;
            var colorB = Background;
            Foreground = Colors.PanelForeground;
            Background = Colors.PanelBackground;

            TERM.Write(OutputSpaceSplitter, false, false, false, true, true);

            X = posX; Y = posY;
            Foreground = colorF;
            Background = colorB;
        }

        public static void DrawInfoSplitter(int row)
        {
            var posX = X; X = OutputColumns;
            var posY = Y; Y = row;
            var colorF = Foreground;
            var colorB = Background;
            Foreground = Colors.SectionInfoSplitter;
            Background = Colors.SectionInfoBackground;

            TERM.Write(InfoSectionSplitter, false, true, false, false);

            X = posX; Y = posY;
            Foreground = colorF;
            Background = colorB;
        }

        public static void DrawSections()
        {
            var posX = X;
            var posY = Y;
            var colorF = Foreground;
            var colorB = Background;

            Background = Colors.SectionInfoBackground;
            DrawPath();
            DrawScreens();
            DrawClock();
            DrawInfoSplitter(Rows - 4);
            DrawHelp();
            DrawInfoSplitter(Rows - 9);
            DrawCurrentTopic();
            DrawInfoSplitter(2);
            DrawStudyTools();
            DrawInfoSplitter(9);
            DrawTutor();

            X = posX;
            Y = posY;
            Foreground = colorF;
            Background = colorB;
        }

        //DimSH.Terminal.Writes a loading indicator (a progress bar)
        private static void InitIndicatorBar(int length, int returnPosition, Action action)
        {
            Foreground = Colors.InitIndicatorBarEnclosure;
            TERM.Write(Separators.InitIndicatorBarBraceLeft, false);
            var pos = X; X += length;
            TERM.Write(Separators.InitIndicatorBarBraceRight, false);
            X = pos; Foreground = Colors.InitIndicatorBarLoading;
            for (int i = 0; i < length; i++)
            {
                TERM.Wait(1, action);
                TERM.Write(Separators.InitIndicatorBarLoading, false);
            }
            X = returnPosition;
        }

        //Writes a placeholder for DONE indicator when the module starts loading
        private static int InitIndicatorStatusLoading(string status = "")
        {
            if (status == "") status = Separators.InitIndicatorStatusLoaded;
            Foreground = Colors.InitIndicatorStatusEnclosure;
            TERM.Write(Separators.InitIndicatorStatusBraceLeft, false);
            Foreground = Colors.InitIndicatorStatusLoading;
            for (int i = 0; i < status.Length; i++)
                TERM.Write(Separators.InitIndicatorStatusLoading, false);
            Foreground = Colors.InitIndicatorStatusEnclosure;
            TERM.Write(Separators.InitIndicatorStatusBraceRight, false);
            return X - status.Length - 1;
        }

        //Writes DONE indicator when the module finishes loading
        private static void InitIndicatorStatusLoaded(int position, int returnPosition)
        {
            X = position;
            Foreground = Colors.InitIndicatorStatusLoaded;
            TERM.Write(Separators.InitIndicatorStatusLoaded, false);
            X = returnPosition;
        }

        //Writes FAIL indicator when the module encounters an error
        public static void InitIndicatorStatusFailed()
        {
            var posX = X; X = _failIndicatorX;
            var posY = Y; Y = _failIndicatorY;

            Foreground = Colors.InitIndicatorStatusFailed;
            TERM.Write(Separators.InitIndicatorStatusFailed, false);

            X = posX; Y = posY;
        }

        public static void DrawInitIndicator(string message, int length, Action actionExternal,
            ConsoleColor colorExternal = Colors.SectionOutputForeground, Action actionInternal = null)
        {
            var pos = InitIndicatorStatusLoading();
            _failIndicatorX = pos; _failIndicatorY = Y - 2;
            Foreground = Colors.InitIndicatorMessage;
            TERM.Write(Tokens.Space + message + Tokens.Space, false);
            InitIndicatorBar(length, pos, actionInternal);
            InitIndicatorStatusLoaded(pos, X);
            TERM.WriteLine(Tokens.NewLine.ToString(), false);
            Foreground = colorExternal;
            if (actionExternal != null) actionExternal.Invoke();
            Foreground = Colors.SectionOutputForeground;
        }

        public static void DrawLogo()
        {
            Foreground = Colors.InitLogo;
            TERM.WriteLine(Messages.Logo, false);
            Foreground = Colors.SectionOutputForeground;
        }

        public static void DrawGreeting()
        {
            Foreground = Colors.InitGreeting;
            TERM.WriteLine(Messages.Greeting, false);
            Foreground = Colors.InitSeparatorFinished;
            TERM.WriteLine(OutputInitSplitter, false);
            TERM.WriteLine(OutputSectionSplitter, false);
            Foreground = Colors.SectionOutputForeground;
        }

        public static void DrawSectionSplitter(bool addSpacing = false, bool init = false)
        {
            var color = Foreground;
            if (init)
            {
                Foreground = Colors.InitSeparatorSection;
                TERM.WriteLine(Tokens.NewLine + OutputSectionSplitter +
                (addSpacing ? Tokens.NewLine.ToString() : ""), false);
            }
            else
            {
                var posX = X; var posY = Y;
                Foreground = Colors.SeparatorSection;
                if (!Settings.AdvancedTerminal) ClearSections();
                X = 0; Y = Rows - 3;
                TERM.Write(OutputSectionSplitter + (addSpacing ?
                    Tokens.NewLine.ToString() : ""), addSpacing);
                X = posX; Y = posY;
                if (!Settings.AdvancedTerminal) DrawSections();
            }
            Foreground = color;
        }

        public static void DrawTree(Node node, bool init = false, string delimiter = "", bool lastNode = true, bool firstRun = true)
        {
            var directory = Settings.AdvancedPaths || node.Content.Children != null;
            Foreground = Colors.InitFileSystem;

            TERM.Write(firstRun ? " " : (delimiter + (lastNode
                ? Symbols.LineCornerBottomLeft : Symbols.LineLeft)
                + Symbols.LineHorizontal), !init, false);

            Foreground = Colors.NodeIndicator;
            TERM.Write(firstRun ? " " : (directory ?
                Symbols.CircleEmpty : Symbols.CircleFull), !init, false);

            Foreground = firstRun ? Colors.OutputIndicatorRoot :
                (directory ? (node.Attributes.System ?
                Colors.NodeSystemFolder : Colors.NodeFolder)
                : (node.Attributes.System ?
                Colors.NodeSystemFile : Colors.NodeFile));
            TERM.WriteLine(node.Name, !init, false);
            
            if (directory)
                for (int i = 0; i < node.Content.Children.Count; i++)
                    DrawTree(node.Content.Children[i], init, delimiter +
                        (lastNode ? "  " : Symbols.LineVertical + " "),
                        i == node.Content.Children.Count - 1, false);
        }

        public static void Initialize()
        {
            Background = Colors.SectionInfoBackground;
            for (int i = 0; i < Rows - 1; i++)
            {
                X = OutputColumns; Y = i;               
                TERM.Write(InfoSpaceSplitter, false);             
            }
            DrawSections();
            X = 0; Y = Rows - 1;
            Foreground = Colors.SectionInputForeground;
            Background = Colors.SectionInputBackground;
        }
    }
}
